package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.crm.handle.explain.impl.ClueExplainHandleImpl;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.PaasFormExplainEntity;
import com.xbongbong.paas.domain.entity.PaasProcessDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasProcessTemplateEntityExt;
import com.xbongbong.paas.elasticsearch.pojo.XbbAggregatedPage;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.elasticsearch.util.EsUtil;
import com.xbongbong.paas.elasticsearch.util.XbbElasticsearchRestTemplate;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.FlowStatusEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.field.ItemPoJo;
import com.xbongbong.paas.help.BusinessUserTeamHelp;
import com.xbongbong.paas.help.CommonHelp;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.parent.help.CommonPermissionHelp;
import com.xbongbong.paas.help.PaasFormHelp;
import com.xbongbong.paas.help.ProSaveHelp;
import com.xbongbong.paas.help.ProUpdateHelp;
import com.xbongbong.paas.help.SaasStageHelp;
import com.xbongbong.paas.help.StageLogHelp;
import com.xbongbong.paas.help.WorkflowTransferHelp;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.log.pojo.InfoArrPojo;
import com.xbongbong.paas.model.PaasFormExplainModel;
import com.xbongbong.paas.model.PaasProcessTemplateModel;
import com.xbongbong.paas.pojo.FieldAttrEntityForImport;
import com.xbongbong.paas.pojo.FormTitlePoJo;
import com.xbongbong.paas.pojo.SummaryDataPoJo;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.pojo.dto.ImportFormDataDTO;
import com.xbongbong.paas.pojo.dto.SaasFormSaveDTO;
import com.xbongbong.paas.pojo.dto.StartProcessDTO;
import com.xbongbong.paas.pojo.dto.ValidateDataDTO;
import com.xbongbong.paas.pojo.imports.CellTitlePojo;
import com.xbongbong.paas.pojo.imports.CellValuePojo;
import com.xbongbong.paas.pojo.imports.RowGroupPojo;
import com.xbongbong.paas.pojo.vo.StartProcessVO;
import com.xbongbong.paas.redis.PaasRedisHelper;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.CallCenterCommonService;
import com.xbongbong.paas.service.ProModelService;
import com.xbongbong.paas.service.team.TeamDataHelp;
import com.xbongbong.paas.service.workflow.trigger.WorkflowFormDataOperationService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CloneUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.util.DateUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.paas.util.ExplainUtil;
import com.xbongbong.paas.util.FormDataUtil;
import com.xbongbong.paas.util.ItemUtil;
import com.xbongbong.pro.applist.pojo.AppListPojo;
import com.xbongbong.pro.applist.pojo.vo.ListAppVO;
import com.xbongbong.pro.businessdata.pojo.dto.FormatExplainDTO;
import com.xbongbong.pro.businessrule.pojo.BusinessRuleInfoPojo;
import com.xbongbong.pro.businesstage.pojo.vo.ChangeClueStatusVO;
import com.xbongbong.pro.clue.pojo.dto.ChangeClueStatusDTO;
import com.xbongbong.pro.common.pojo.dto.CustomerCheckRepeatDTO;
import com.xbongbong.pro.constant.ElasticConstant;
import com.xbongbong.pro.customer.pojo.dto.ClueDeleteBatchDTO;
import com.xbongbong.pro.customer.pojo.dto.CustomerEditAttrUpdateDTO;
import com.xbongbong.pro.customer.pojo.vo.CustomerEditAttrUpdateVO;
import com.xbongbong.pro.customercommunicate.pojo.dto.CustomerCommunicateDeleteBatchDTO;
import com.xbongbong.pro.domain.entity.UpdateDataEntity;
import com.xbongbong.pro.domain.entity.UpdateDataValueEntity;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.errorcodes.ClueErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.UserTeamErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.ProPermissionAliasEnum;
import com.xbongbong.pro.enums.workflow.TriggerEventTypeEnum;
import com.xbongbong.pro.formdata.pojo.AfterSavePojo;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainDTO;
import com.xbongbong.pro.formexplain.pojo.dto.HandlerExplainInLinkItemDTO;
import com.xbongbong.pro.listbatch.pojo.dto.AddLabelDTO;
import com.xbongbong.pro.listbatch.pojo.dto.ListBatchDTO;
import com.xbongbong.pro.marketManage.pojo.dto.ClueUpdateBatchDTO;
import com.xbongbong.pro.marketManage.pojo.dto.ClueUpdateDTO;
import com.xbongbong.pro.message.constant.CluePushConstant;
import com.xbongbong.pro.message.enums.PushTypeEnum;
import com.xbongbong.pro.message.help.PushHelper;
import com.xbongbong.pro.message.pojo.PushRefTypePojo;
import com.xbongbong.pro.message.pojo.dto.AutoClueAssignmentRabbitMqDTO;
import com.xbongbong.pro.message.pojo.dto.MessageRabbitMqDTO;
import com.xbongbong.pro.message.pojo.dto.PublicGroupRabbitMqDTO;
import com.xbongbong.pro.opportunity.pojo.JudgeStageChangedPojo;
import com.xbongbong.pro.opportunity.pojo.vo.ClueDeleteBatchVO;
import com.xbongbong.pro.opportunity.pojo.vo.ClueUpdateBatchVO;
import com.xbongbong.pro.opportunityuser.pojo.dto.ClueUserDeleteBatchDTO;
import com.xbongbong.pro.permission.pojo.dto.VerifyUpdatePermissionDTO;
import com.xbongbong.pro.rabbitmq.producer.AutoClueAssignmentProducer;
import com.xbongbong.pro.rabbitmq.producer.BaseProducer;
import com.xbongbong.pro.rabbitmq.producer.PublicGroupProducer;
import com.xbongbong.pro.service.toolbox.elasticsearch.help.ProEsHelper;
import com.xbongbong.pro.thread.ThreadPoolBeanConfig;
import com.xbongbong.pro.workflow.enums.WorkflowOperateEnum;
import com.xbongbong.process.operate.ProcessStartHelp;
import com.xbongbong.saas.analytical.impl.ClueValidateAnalyticalServiceImpl;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ErrorMessageConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.ClueStageEntity;
import com.xbongbong.saas.domain.entity.ClueUserEntity;
import com.xbongbong.saas.domain.entity.StaticForUpdateDTO;
import com.xbongbong.saas.domain.entity.TagLinkEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.domain.entity.ext.ClueEntityExt;
import com.xbongbong.saas.enums.CheckRepeatRuleEnum;
import com.xbongbong.saas.enums.FormConfigEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ClueEnum;
import com.xbongbong.saas.enums.business.CustomerCommunicateEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.enums.business.MarketActivityEnum;
import com.xbongbong.saas.enums.dictionary.ClueStatusEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.help.ImportHelper;
import com.xbongbong.saas.help.LogHandleHelp;
import com.xbongbong.saas.help.MarketManagementBusinessHelp;
import com.xbongbong.saas.help.SaasDeleteHelp;
import com.xbongbong.saas.help.SaasDetailPermissionHelp;
import com.xbongbong.saas.help.SaasGetHelp;
import com.xbongbong.saas.help.SaasListHelp;
import com.xbongbong.saas.help.SaasUpdateHelp;
import com.xbongbong.saas.help.ScoreCalculateHelp;
import com.xbongbong.saas.help.workflow.MarketActivityForStaticHelp;
import com.xbongbong.saas.model.ClueModel;
import com.xbongbong.saas.model.ClueStageLogModel;
import com.xbongbong.saas.model.ClueStageModel;
import com.xbongbong.saas.model.ClueUserModel;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.model.TagLinkModel;
import com.xbongbong.saas.service.ClueService;
import com.xbongbong.saas.service.ClueStageLogService;
import com.xbongbong.saas.service.ClueUserService;
import com.xbongbong.saas.service.CustomerCommunicateService;
import com.xbongbong.saas.service.ListBatchService;
import com.xbongbong.saas.service.MarketActivityForStaticService;
import com.xbongbong.saas.service.ScoreCalculateService;
import com.xbongbong.saas.service.ScoreRuleService;
import com.xbongbong.saas.service.UserTeamService;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import com.xbongbong.saas.service.toolbox.help.UserTeamHelp;
import com.xbongbong.saas.toolbox.help.FastJsonHelper;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.enums.DataPermissionEnum;
import com.xbongbong.sys.help.ProPermissionHelp;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.workflow.domain.entity.WorkflowBackupDataEntity;
import com.xbongbong.workflow.domain.entity.WorkflowEntity;
import com.xbongbong.workflow.domain.entity.WorkflowNodeEntity;
import com.xbongbong.workflow.model.WorkflowBackupDataModel;
import com.xbongbong.workflow.model.WorkflowNodeModel;
import com.xbongbong.workflow.pojo.Data;
import com.xbongbong.workflow.pojo.WorkflowRabbitmqDTO;
import com.xbongbong.workflow.pojo.WorkflowTransferPOJO;
import com.xbongbong.workflow.pojo.nodes.FormTriggerNode;
import com.xbongbong.workflow.producer.WorkflowProducer;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.client.core.CountRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.xbongbong.paas.elasticsearch.constant.EsNormalConstant.MINI_MUM_SHOULD_MATCH;
import static com.xbongbong.saas.toolbox.help.FastJsonHelper.getIntegerOrDefaultFromFormData;
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

/**
 * @author long
 * @version v1.0
 * @date 2020/11/4 10:35
 * @since v1.0
 */
@Service("clueService")
public class ClueServiceImpl implements ClueService {
    private static final Logger LOG = LoggerFactory.getLogger(ClueServiceImpl.class);

    @Resource
    private SaasUpdateHelp saasUpdateHelp;
    @Resource
    private ClueModel clueModel;
    @Resource
    private UserTeamService userTeamService;
    @Resource
    private UserModel userModel;
    @Resource
    @Lazy
    private CustomerCommunicateService customerCommunicateService;
    @Resource
    private ThreadPoolBeanConfig threadPoolBeanConfig;
    @Resource
    private XbbElasticsearchRestTemplate xbbElasticsearchRestTemplate;
    @Resource
    private TagLinkModel tagLinkModel;
    @Resource
    private CallCenterCommonService callCenterCommonService;
    @Resource
    private CommonHelp commonHelp;
    @Resource
    private ClueStageModel clueStageModel;
    @Resource
    private ClueStageLogModel clueStageLogModel;
    @Resource
    private ClueStageLogService clueStageLogService;
    @Resource
    private EsHelper esHelper;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private ClueUserService clueUserService;
    @Resource
    private ListBatchService listBatchService;
    @Resource
    private ImportHelper importHelper;
    @Resource
    private DataDictionaryModel dataDictionaryModel;
    @Resource
    private ProEsHelper proEsHelper;
    @Resource
    private PaasProcessTemplateModel paasProcessTemplateModel;
    @Resource
    private SaasGetHelp saasGetHelp;
    @Resource
    private FormDataHelp formDataHelp;
    @Resource
    private PushHelper pushHelper;
    @Resource
    private ClueUserModel clueUserModel;
    @Resource
    private BaseProducer baseProducer;
    @Resource
    private ProcessStartHelp processStartHelp;
    @Resource
    private ProModelService proModelService;
    @Resource
    private ScoreCalculateService scoreCalculateService;
    @Resource
    private LogHelp logHelp;
    @Resource
    private ScoreRuleService scoreRuleService;
    @Resource
    private MarketActivityForStaticService marketActivityForStaticService;
    @Resource
    private MarketManagementBusinessHelp marketManagementBusinessHelp;
    @Resource
    private SaasListHelp saasListHelp;
    @Resource
    private LogHandleHelp logHandleHelp;
    @Resource
    private ScoreCalculateHelp scoreCalculateHelp;
    @Resource
    private AutoClueAssignmentProducer autoClueAssignmentProducer;
    @Resource
    private PaasRedisHelper paasRedisHelper;
    @Resource
    private SaasDetailPermissionHelp saasDetailPermissionHelp;
    @Resource
    private ProUpdateHelp proUpdateHelp;
    @Resource
    private CommonPermissionHelp commonPermissionHelp;
    @Resource
    private ClueValidateAnalyticalServiceImpl clueAnalyticalService;
    @Resource
    private WorkflowNodeModel workflowNodeModel;
    @Resource
    private WorkflowFormDataOperationService workflowFormDataOperationService;
    @Resource
    private WorkflowBackupDataModel workflowBackupDataModel;
    @Resource
    private WorkflowProducer workflowProducer;
    @Resource
    private PaasFormExplainModel paasFormExplainModel;
    @Resource
    private PaasFormHelp paasFormHelp;
    @Resource
    private StageLogHelp stageLogHelp;
    @Resource
    private SaasStageHelp saasStageHelp;
    @Resource
    private IndexTypeModel indexTypeModel;
    @Resource
    private UserTeamHelp userTeamHelp;
    @Resource
    private TeamDataHelp teamDataHelp;
    @Resource
    private ClueExplainHandleImpl clueExplainHandle;

    @Resource
    private PublicGroupProducer publicGroupProducer;
    @Resource
    private MarketActivityForStaticHelp marketActivityForStaticHelp;

    @Override
    public void beforeSave(ValidateDataDTO validateDataDTO) throws XbbException {
        clueAnalyticalService.beforeSave(validateDataDTO);
    }

    @Override
    public AfterSavePojo afterSave(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        AfterSavePojo afterSavePojo = new AfterSavePojo();
        String corpid = saasFormSaveDTO.getCorpid();
        Integer businessType = saasFormSaveDTO.getBusinessType();
        JSONObject newData = saasFormSaveDTO.getNewData();
        JSONObject oldData = saasFormSaveDTO.getOldData();
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long dataId = newPaasFormDataEntity.getId();
        Boolean isNew = saasFormSaveDTO.getIsNew();
        Long formId = newPaasFormDataEntity.getFormId();
        String companyName = FastJsonHelper.getStringOrDefaultFromFormData(newData, ClueEnum.COMPANY_NAME.getAttr(), "");
        String stageCode = FastJsonHelper.getStringOrDefaultFromFormData(newData, ClueEnum.CLUE_STAGE.getAttr(), "");
        Integer reasonId = getIntegerOrDefaultFromFormData(newData, ClueEnum.INVALID_REASON.getAttr(), BasicConstant.ZERO);
        String invalidMemo = FastJsonHelper.getStringOrDefaultFromFormData(newData, ClueEnum.INVALID_MEMO.getAttr(), "");
        Long stageId = FastJsonHelper.getLongOrDefaultFromFormData(newData, ClueEnum.STAGE_ID.getAttr(), BasicConstant.ZERO_LONG);
        if (Objects.isNull(saasFormSaveDTO.getOwnerId()) || (Objects.nonNull(saasFormSaveDTO.getOwnerId()) && saasFormSaveDTO.getOwnerId().isEmpty())) {
            saasFormSaveDTO.setSubBusinessType(XbbRefTypeEnum.CLUE_PUBLIC.getCode());
        }
        Integer isPublic = getIntegerOrDefaultFromFormData(newData, ClueEnum.IS_PUBLIC.getAttr(), 0);
        if (!Objects.equals(saasFormSaveDTO.getIsImport(), 1) && isNew && Objects.equals(isPublic, 1)) {
            AutoClueAssignmentRabbitMqDTO mqDTO = new AutoClueAssignmentRabbitMqDTO(corpid, Collections.singletonList(dataId), newPaasFormDataEntity.getFormId());
            autoClueAssignmentProducer.autoClueAssignment(mqDTO);
        }

        // 新建的时候阶段不为空或者编辑时阶段不一致才需要更改阶段
        JudgeStageChangedPojo judgeStageChangedPojo = stageLogHelp.judgeStageChanged(corpid, formId, dataId, stageCode, SaasMarkEnum.SAAS.getCode(), XbbRefTypeEnum.CLUE.getCode());
        if (judgeStageChangedPojo.getIsStageChanged()) {
            try {
                saasStageHelp.stageJump(saasFormSaveDTO, ClueEnum.CLUE_STAGE.getAttr());
            } catch (Exception e) {
                LOG.error("线索阶段变更消息推送", e);
            }
        }

        if (Objects.equals(saasFormSaveDTO.getSubBusinessType(), XbbRefTypeEnum.CLUE_PUBLIC.getCode())) {
            if (!isNew && !Objects.equals(oldData.getInteger(ClueEnum.IS_PUBLIC.getAttr()), 1)) {
                ListBatchDTO listBatchDTO = new ListBatchDTO();
                BeanUtil.copyProperties(saasFormSaveDTO, listBatchDTO);
                listBatchDTO.setDataIdList(new ArrayList<>(Collections.singletonList(dataId)));
                listBatchDTO.setBusinessType(XbbRefTypeEnum.CLUE.getCode());
                listBatchDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                listBatchDTO.setFormId(newPaasFormDataEntity.getFormId());
                // 新建编辑场景没有团队需要退回公海池，防止当前操作人没有退回公海池权限导致下面的方法执行成功，补充权限
                listBatchDTO.getLoginUser().getPermSet().add(ProPermissionAliasEnum.CLUE_BACK.getAlias());
                // 退回公海池
                listBatchService.backCustomer(listBatchDTO);
            } else {
                // 团队保存
                SaasNeedRedundantAttrPojo saasNeedRedundantAttrPoJo = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo();
                afterSavePojo = teamDataHelp.saveUserTeam(saasNeedRedundantAttrPoJo, saasFormSaveDTO.getNewPaasFormDataEntity().getId(), saasFormSaveDTO.getNewPaasFormDataEntity(), saasFormSaveDTO.getIsImport(), false);
            }
        } else {
            // 团队保存
            SaasNeedRedundantAttrPojo saasNeedRedundantAttrPoJo = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo();
            afterSavePojo = teamDataHelp.saveUserTeam(saasNeedRedundantAttrPoJo, saasFormSaveDTO.getNewPaasFormDataEntity().getId(), saasFormSaveDTO.getNewPaasFormDataEntity(), saasFormSaveDTO.getIsImport(), false);
            if (!afterSavePojo.getHaveTeam()) {
                ListBatchDTO listBatchDTO = new ListBatchDTO();
                BeanUtil.copyProperties(saasFormSaveDTO, listBatchDTO);
                listBatchDTO.setDataIdList(Collections.singletonList(dataId));
                listBatchDTO.setBusinessType(XbbRefTypeEnum.CLUE.getCode());
                listBatchDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
                listBatchDTO.setFormId(newPaasFormDataEntity.getFormId());
                // 新建编辑场景没有团队需要退回公海池，防止当前操作人没有退回公海池权限导致下面的方法执行成功，补充权限
                listBatchDTO.getLoginUser().getPermSet().add(ProPermissionAliasEnum.CLUE_BACK.getAlias());
                // 退回公海池
                listBatchService.backCustomer(listBatchDTO);
            }
        }

        String creatorId = newPaasFormDataEntity.getCreatorId();
        UserEntity creatorUser = userModel.getByKey(creatorId, corpid);
        // 线索创建消息推送
        ClueEntityExt clueEntityExt = new ClueEntityExt();
        BeanUtil.copyProperties(newPaasFormDataEntity, clueEntityExt);
        List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(saasFormSaveDTO.getCorpid(), PushTypeEnum.CLUE_ADD_PUSH.getCode(), PushTypeEnum.CLUE_ADD_PUSH.getSubCode(), creatorUser, clueEntityExt);
        Runnable runnable = () -> {
            if (isNew) {
                try {
                    if (!Objects.equals(saasFormSaveDTO.getIsImport(), 1)) {
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(newPaasFormDataEntity.getAppId(), newPaasFormDataEntity.getMenuId(), newPaasFormDataEntity.getFormId(), dataId, Collections.singletonList(dataId), SaasMarkEnum.SAAS.getCode(), saasFormSaveDTO.getBusinessType(), saasFormSaveDTO.getSubBusinessType());
                        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(saasFormSaveDTO.getCorpid(), pushUserList, Collections.singletonList(dataId), 0, null, I18nMessageUtil.getMessage(CluePushConstant.CLUE_ADD_TITLE), String.format(I18nMessageUtil.getMessage(CluePushConstant.CLUE_ADD_CONTENT), creatorUser.getName(), companyName), null, options);
                        baseProducer.sendMessage(PushTypeEnum.CLUE_ADD_PUSH, messageRabbitMqDTO);
                    }
                } catch (Exception e) {
                    LOG.error("线索创建消息推送", e);
                }
            }

            try {
                //计算评分（线索的编辑和导入时数据的覆盖底层都是走到这里）
                PaasFormDataEntityExt paasFormDataEntityExt = new PaasFormDataEntityExt();
                BeanUtil.copyProperties(newPaasFormDataEntity,paasFormDataEntityExt);
                scoreCalculateService.asyncUpdateSingleDataScore(XbbRefTypeEnum.CLUE,corpid,dataId,paasFormDataEntityExt);
            } catch (Exception e) {
                LOG.error("e{}",e.getMessage());
            }
            try {
                //根据分组规则绑定所属分组
                boolean cluePublicPoolSeniorModel = commonHelp.isCluePublicPoolSeniorModel(corpid);
                if (cluePublicPoolSeniorModel && isNew && !Objects.equals(saasFormSaveDTO.getIsImport(), 1)) {
                    PublicGroupRabbitMqDTO mqDTO = new PublicGroupRabbitMqDTO(corpid, Collections.singletonList(dataId), newPaasFormDataEntity.getFormId(), businessType);
                    publicGroupProducer.bindPublicGroup(mqDTO);
                }
            } catch (Exception e) {
                LOG.error("分组规则绑定所属分组失败{}",e.getMessage());
            }


        };
        threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
        return afterSavePojo;
    }



    @Override
    public void formatLinkAddExplain(HandlerExplainInLinkItemDTO handlerExplainInLinkItemDTO) throws XbbException {
        JSONObject linkFormData = handlerExplainInLinkItemDTO.getLinkFormData();
        Long linkDataId = handlerExplainInLinkItemDTO.getLinkDataId();
        List<FieldAttrEntity> explainList = handlerExplainInLinkItemDTO.getExplainList();
        FieldAttrEntity linkMarkActivityField = new FieldAttrEntity();
        for(FieldAttrEntity fieldAttrEntity :explainList) {
            if (Objects.equals(fieldAttrEntity.getAttr(), ClueEnum.MARKET_ACTIVITY_ID.getAttr())) {
                linkMarkActivityField = fieldAttrEntity;
            }
        }
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(handlerExplainInLinkItemDTO.getLinkBusinessType());
        switch (redundantTemplateTypeEnum) {
            case MARKET_ACTIVITY:
                String markActivityName = FastJsonHelper.getStringOrDefaultFromFormData(linkFormData, MarketActivityEnum.NAME.getAttr(), "");
                linkMarkActivityField.setDefaultAttr(saasUpdateHelp.getDefaultAttrPojo(linkDataId, markActivityName));
                break;
            default:
                break;
        }
    }

    @Override
    public FormDataAddDTO formatExcelValue(ImportFormDataDTO importFormDataDTO, List<CellTitlePojo> titlePojoList, RowGroupPojo rowGroupPojo, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        FormDataAddDTO formDataAddDTO = new FormDataAddDTO();
        BeanUtil.copyProperties(importFormDataDTO, formDataAddDTO);
        formDataAddDTO.setSerialNo("");
        JSONObject dataJson = new JSONObject();
        List<List<CellValuePojo>> rowValueList = rowGroupPojo.getRowValueList();
        // 分组的第一条数据作为给实体对象赋值的数据
        List<CellValuePojo> cellValueList = rowValueList.get(0);
        Map<String, FieldAttrEntity> explainMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        for (FieldAttrEntityForImport fieldAttr : fieldAttrList) {
            String attr = fieldAttr.getAttr();
            Integer fieldType = fieldAttr.getFieldType();
            String attrName = fieldAttr.getAttrName();
            Integer columnIndex = importHelper.getColumnIndexByTitle(titlePojoList, attrName, null);
            Object cellValue = importHelper.getValueByColumnIndex(cellValueList, columnIndex);
            if (Objects.equals(fieldType, FieldTypeEnum.SUB_FORM.getType())) {
                importHelper.formatSubFormValue4Import(rowValueList, titlePojoList, importFormDataDTO, fieldAttr, dataJson);
            } else if (Objects.equals(attr, ClueEnum.MARKET_ACTIVITY_ID.getAttr())) {
                // 关联市场活动根据linkedType判断
                importHelper.formatSuppplier2SupplierId(cellValue.toString(), dataJson, fieldAttr);
            } else {
                if (Objects.isNull(cellValue) || StringUtil.isEmpty(cellValue.toString())) {
                    continue;
                }
                if (ImportHelper.commonHandleFieldType.contains(fieldAttr.getFieldType())) {
                    importHelper.formatCommonField(dataJson, fieldAttr, cellValue);
                    if (Objects.equals(fieldAttr.getAttr(), ClueEnum.CLUE_STAGE.getAttr())) {
                        String stageCode = dataJson.getString(attr);
                        ClueStageEntity clueStageEntity = null;
                        if (StringUtil.isNotEmpty(stageCode)) {
                            clueStageEntity = clueStageModel.getByCode(importFormDataDTO.getCorpid(), importFormDataDTO.getFormId(), stageCode);
                        }
                        if (Objects.nonNull(clueStageEntity) && Objects.equals(clueStageEntity.getType(), StageTypeEnum.FAIL_STAGE.getType())) {
                            // 无效原因必填
                            List<ItemPoJo> dictionaryList4Saas = dataDictionaryModel.getDictionaryList4Saas(DictionaryEnum.CLUE_STAGE_INVALID, importFormDataDTO.getCorpid(), importFormDataDTO.getFormId());
                            if (!dictionaryList4Saas.isEmpty()) {
                                dataJson.put(ClueEnum.INVALID_REASON.getAttr(), dictionaryList4Saas.get(0).getValue());
                            }
                        }
                    }
                } else {
                    if (Objects.equals(fieldType, FieldTypeEnum.SERIALNO.getType())) {
                        formDataAddDTO.setSerialNo(cellValue.toString());
                    } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA.getType())) {
                        importHelper.formatLinkData(cellValue, fieldAttr, dataJson);
                    } else if (Objects.equals(fieldType, FieldTypeEnum.LINK_DATA_MULTI.getType())) {
                        importHelper.formatLinkDataMulti(cellValue, importFormDataDTO, fieldAttr, dataJson);
                    } else {
                        dataJson.put(attr, cellValue);
                    }
                }
            }
        }
        formDataAddDTO.setDataList(dataJson);
        return formDataAddDTO;
    }

    @Override
    public void formatExportValue(List<PaasFormDataEntityExt> paasFormDataESList, List<FieldAttrEntityForImport> fieldAttrList) throws XbbException {
        Integer showPublicPool = 0;
        Integer publicPool = 0;
        for (FieldAttrEntityForImport fieldAttrEntityForImport : fieldAttrList) {
            if (Objects.equals(fieldAttrEntityForImport.getAttr(), ClueEnum.PHONE.getAttr())) {
                showPublicPool = fieldAttrEntityForImport.getShowPublicPool();
                publicPool = fieldAttrEntityForImport.getPublicPool();
                continue;
            }
        }
        for (PaasFormDataEntityExt paasFormDataEntityExt : paasFormDataESList) {
            JSONObject data = paasFormDataEntityExt.getData();
            Integer isPublic = getIntegerOrDefaultFromFormData(data, ClueEnum.IS_PUBLIC.getAttr(), BasicConstant.ZERO);
            if (Objects.equals(isPublic, BasicConstant.ONE) && Objects.equals(showPublicPool, BasicConstant.ONE) && Objects.equals(publicPool, BasicConstant.ZERO)) {
                // 如果在模板电话字段，选了公海池不可见，那么公海线索的电话就不可见
                data.put(ClueEnum.PHONE.getAttr(), new JSONArray());
            }
        }
    }

    @Override
    public void formatAddExplain(FormatExplainDTO formatExplainDTO) throws XbbException {
       clueExplainHandle.newHandleExplain(formatExplainDTO);
    }

    @Override
    public XbbAggregatedPage<PaasFormDataEntityExt> getDuplicateClue(CustomerCheckRepeatDTO customerCheckRepeatDTO) throws XbbException {
        CheckRepeatRuleEnum checkRepeatRuleEnum = CheckRepeatRuleEnum.getByCode(customerCheckRepeatDTO.getRule());
        if (Objects.isNull(checkRepeatRuleEnum)) {
            // 默认按名字查重
            checkRepeatRuleEnum = CheckRepeatRuleEnum.NAME;
        }
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword",customerCheckRepeatDTO.getCorpid() ));
        boolQueryBuilder.filter(termsQuery("del", Arrays.asList(DelEnum.NORMAL.getDel(),DelEnum.DELETE.getDel(),DelEnum.APPROVE_STATUS.getDel())));
        if (customerCheckRepeatDTO.getIsOpenWorkflow()) {
            boolQueryBuilder.filter(termsQuery(FieldTypeEnum.FLOW_STATUS.getAlias(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType(), FlowStatusEnum.APPROVAL_PENDING.getType(), FlowStatusEnum.IN_APPROVAL.getType())));
        } else {
            boolQueryBuilder.filter(termsQuery(FieldTypeEnum.FLOW_STATUS.getAlias(), Arrays.asList(FlowStatusEnum.NOT_NEED_APPROVAL.getType(), FlowStatusEnum.PASS.getType())));
        }
        switch (checkRepeatRuleEnum){
            case NAME:
                boolQueryBuilder.should(termQuery("data." + ClueEnum.COMPANY_NAME.getAttr() + ".keyword",customerCheckRepeatDTO.getNameLike()).boost(2));
                boolQueryBuilder.should(matchPhraseQuery("data." + ClueEnum.COMPANY_NAME.getAttr(),customerCheckRepeatDTO.getNameLike()));
                break;
            case PHONE:
                boolQueryBuilder.should(termQuery("data." + ClueEnum.PHONE.getAttr() + ".text_2" + ".keyword",customerCheckRepeatDTO.getNameLike()).boost(2));
                boolQueryBuilder.should(matchPhraseQuery("data." + ClueEnum.PHONE.getAttr() + ".text_2",customerCheckRepeatDTO.getNameLike()));
                break;
            default:
                break;
        }
        boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD,IndexTypeEnum.IDX_SAAS_CLUE.getType()));
        boolQueryBuilder.minimumShouldMatch(MINI_MUM_SHOULD_MATCH);
        Integer page = 1;
        Integer pageSize = 10;
        PageRequest pageRequest = EsUtil.setPage(sourceBuilder, (page - 1), pageSize);
        sourceBuilder.query(boolQueryBuilder);
        SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
        searchRequest.source(sourceBuilder);
        XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
        return esEntities;
    }

    @Override
    public ListAppVO formatClueAppList(FormDataListDTO formDataListDTO, List<PaasFormDataEntityExt> esEntities, Integer totalCount) throws XbbException {
        List<AppListPojo> appListPojos = new ArrayList<>();
        String corpid = formDataListDTO.getCorpid();
        String userId = formDataListDTO.getUserId();
        Long formId = formDataListDTO.getFormId();
        Integer businessType = formDataListDTO.getBusinessType();
        Integer subBusinessType = formDataListDTO.getSubBusinessType();
        UserEntity userEntity = userModel.getByKey(userId, corpid);
        List<Long> idIn = new ArrayList<>();
        idIn.add(-1L);
        for (PaasFormDataEntityExt customer : esEntities) {
            idIn.add(customer.getDataId());
        }
        //有提醒的客户
        List<Long> pushNotifyList = new ArrayList<>();
        saasListHelp.getPushNotify(idIn, corpid, XbbRefTypeEnum.CLUE.getCode(), pushNotifyList);
        // 获取退字标签
        Map<Long, TagLinkEntity> tagMap = tagLinkModel.getPublicTagLink(corpid, idIn, XbbRefTypeEnum.CLUE_PUBLIC.getCode());
        // 转移标签
        Map<Long, TagLinkEntity> transferTagMap = tagLinkModel.getPublicTagLink(corpid, idIn, XbbRefTypeEnum.CLUE_TRANSFER.getCode());

        Map<String, FieldAttrEntity> explainMap = formDataListDTO.getExplainMap();
        // 呼叫中心权限
        boolean isActiveCall = callCenterCommonService.isOpenCallDingTalk(corpid, userId);

        //协同团队
        Map<Long, List<String>> mainUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<Long, List<String>> coUserMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Boolean isPublic = Objects.equals(XbbRefTypeEnum.CLUE_PUBLIC.getCode(),subBusinessType);
        userTeamService.getUserIdMap(idIn,corpid,formDataListDTO.getBusinessType(),isPublic,mainUserMap,coUserMap);
        HandlerExplainDTO handlerExplainDTO = new HandlerExplainDTO();
        BeanUtil.copyProperties(formDataListDTO, handlerExplainDTO);

        for (PaasFormDataEntityExt clue : esEntities) {
            JSONObject data = clue.getData();
            Long clueId = clue.getDataId();
            Long appId = clue.getAppId();
            Long menuId = clue.getMenuId();
            String name = FastJsonHelper.getStringOrDefaultFromFormData(data, ClueEnum.COMPANY_NAME.getAttr(), "");

            JSONObject superScript = new JSONObject();
            JSONObject others = new JSONObject();

            List<SummaryDataPoJo> summaryList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.SUMMARY_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<SummaryDataPoJo> lablesList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.LABELS_LIST, new JSONArray()).toJavaList(SummaryDataPoJo.class);
            List<FormTitlePoJo> titleList = FastJsonHelper.getJsonArrOrDefaultFromFormData(data, BasicConstant.TITLE_LIST, new JSONArray()).toJavaList(FormTitlePoJo.class);
            // isAchived为1代表归档，2代表未归档
            JSONObject tagData = clue.getTagData();
            if(Objects.equals(tagData.getInteger("isAchived"), 1)){
                superScript.put("archived", 1);
            }
            // 角标 -
            superScript.put("message", pushNotifyList.contains(clueId) ? 1 : 0);
            // 退字标签
            if(tagMap.containsKey(clueId)){
                superScript.put("back", tagMap.getOrDefault(clueId, new TagLinkEntity()));
            }
            // 转移标签
            if(Objects.nonNull(transferTagMap) && transferTagMap.containsKey(clueId)){
                superScript.put("transfer", transferTagMap.getOrDefault(clueId, new TagLinkEntity()));
            }
            //其他,放入评分(在前面的查询列表时，已经处理过一次评分的值，这里直接拿出来)
            if(!marketManagementBusinessHelp.feeTypeIsStandardOrAppIsClosed(corpid) && scoreRuleService.haveEnabledScoreRule(corpid,formId)){
                others.put("score",data.get(ClueEnum.SCORE.getAttr()));
            }
            //最后跟进时间
            String lastConnectTimeStr = FastJsonHelper.getStringOrDefaultFromFormData(data, ClueEnum.LAST_CONNECT_TIME.getAttr(), I18nMessageUtil.getMessage(StringConstant.NEVER_CONNECT));
            // 最后跟进时间格式标识
            if(Objects.nonNull(data.get(FormConfigEnum.CLUE_LAST_CONNECT_TIME.getDbAlias()))){
                String lastConnectTime = data.get(FormConfigEnum.CLUE_LAST_CONNECT_TIME.getDbAlias()).toString();
                if(Objects.equals(lastConnectTime, "0")){
                    Long time = Long.valueOf(lastConnectTimeStr);
                    lastConnectTimeStr = DateUtil.getString(time * 1000L, DateUtil.SDFYMDHM);
                }
            }

            // 当前数据的创建人、负责人、协同人、当前操作人
            handlerExplainDTO.setOwnerId(mainUserMap.get(clueId));
            handlerExplainDTO.setCoUserId(coUserMap.get(clueId));
            handlerExplainDTO.setCreatorId(clue.getCreatorId());
            boolean stageOpen = CommonHelp.ifStageOpen(XbbRefTypeEnum.CLUE.getCode(), explainMap, handlerExplainDTO);

            if (stageOpen) {
                String clueStageStr = ItemUtil.parseItemPoJoFromFormData2String(data, ClueEnum.CLUE_STAGE.getAttr(), "");
                if (!clueStageStr.isEmpty()) {
                    others.put("stage", clueStageStr);
                }
            }
//            boolean scoreOpen = commonHelp.ifScoreOpen(XbbRefTypeEnum.CLUE.getCode(), explainMap, handlerExplainDTO);

//            if (scoreOpen) {
//                String clueScoreStr = FastJsonHelper.getStringOrDefaultFromFormData(data, ClueEnum.SCORE.getAttr(), "");
//                if (StringUtil.isNotEmpty(clueScoreStr)) {
//                    others.put("score", clueScoreStr);
//                }
//            }
            if(Objects.equals(XbbRefTypeEnum.CLUE_PUBLIC.getCode(), subBusinessType)){
                others.put("isGrab",1);
            }
            boolean isShowCallCenterPhone = false;
            if (!Objects.equals(XbbRefTypeEnum.CLUE_PUBLIC.getCode(), subBusinessType)) {
                isShowCallCenterPhone = true;
            }
            boolean isShowCall = isActiveCall && isShowCallCenterPhone;
            if(isShowCall){
                saasListHelp.setClueCallPhone(userEntity, explainMap, clue, others, clue.getCreatorId(), formDataListDTO.getLoginUser());
            }
            others.put("isCallCenter", isActiveCall);
            String finalLastConnectTimeStr = lastConnectTimeStr;
            summaryList.forEach(item -> {
                if (Objects.equals(item.getAttr(), ClueEnum.LAST_CONNECT_TIME.getAttr())) {
                    item.setValue(Collections.singletonList(finalLastConnectTimeStr));
                } else if (Objects.equals(item.getAttr(), ClueEnum.ADDRESS.getAttr())) {
                    item.setAttrName(ClueEnum.ADDRESS.getAttrName());
                }
            });
            Boolean activeAliyunCall = callCenterCommonService.isActiveAliyunCall(corpid, userId).IsActiveAliyunAndHasRole();
            boolean showAliyunCall = saasListHelp.checkShowCall(userEntity, explainMap, clue);
            if(activeAliyunCall&&showAliyunCall){
                superScript.put("activeAliyunCall", 1);
            }else{
                superScript.put("activeAliyunCall", 0);
            }
            //app系统关联数据展示需要 others 和 superScript
            data.put("others",others);
            data.put("superScript",superScript);
            appListPojos.add(new AppListPojo(clueId, titleList, summaryList, superScript, lablesList, others, appId, menuId, formId, name,businessType,clueId));
        }
        ListAppVO listAppVO = new ListAppVO();
        listAppVO.setList(appListPojos);
        listAppVO.setTotalCount(totalCount);
        return  listAppVO;
    }

    @Override
    public ClueDeleteBatchVO deleteBatch(ClueDeleteBatchDTO clueDeleteBatchDTO) throws XbbException {
        ClueDeleteBatchVO clueDeleteBatchVO = new ClueDeleteBatchVO();
        List<Long> idIn = clueDeleteBatchDTO.getDataIdList();
        String corpid = clueDeleteBatchDTO.getCorpid();
        Set<Long> lockClues = clueAutoAssignmentLocking(idIn,corpid);
        List<PaasFormDataEntityExt> clueList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(idIn)) {
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            boolQueryBuilder.filter(termsQuery(StringConstant.DATA_ID, idIn));
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_CLUE.getType()));
            List<String> fieldList = Arrays.asList(StringConstant.SAAS_LINK_BUSINESS_ID, StringConstant.JSON_DATA, StringConstant.CORPID, StringConstant.DATA_ID);
            clueList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CLUE, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
            if (Objects.isNull(clueList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
        }
        Set<String> errorTypeSet = new HashSet<>();
        List<String> errorDataList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(lockClues)) {
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            boolQueryBuilder.filter(termsQuery(StringConstant.DATA_ID, idIn));
            boolQueryBuilder.filter(termQuery(ElasticConstant.MY_JOIN_FIELD, IndexTypeEnum.IDX_SAAS_CLUE.getType()));
            sourceBuilder.query(boolQueryBuilder);
            List<String> fieldList = new ArrayList<>();
            fieldList.add(ParameterConstant.APPID);
            fieldList.add(ParameterConstant.MENUID);
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.COMPANY_NAME));
            fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.IS_PUBLIC));
            fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.CLUE_STATUS));
            fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.CLUE_SOURCE));
            fieldList.add(ClueEnum.getAttrConnectData(ClueEnum.LABEL));
            String[] strings = new String[fieldList.size()];
            sourceBuilder.fetchSource(fieldList.toArray(strings),null);

            SearchRequest searchRequest = new SearchRequest(IndexTypeEnum.IDX_SAAS_CLUE.getIndex());
            PageRequest pageRequest = EsUtil.setPage(sourceBuilder, 0, idIn.size());
            searchRequest.source(sourceBuilder);
            XbbAggregatedPage<PaasFormDataEntityExt> esEntities = xbbElasticsearchRestTemplate.queryForPages(pageRequest, searchRequest, PaasFormDataEntityExt.class);
            if (esEntities == null) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            for (PaasFormDataEntityExt entityExt : esEntities.getContent()) {
                errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.CLUE_AUTO_ASSIGNING));
                String name = FastJsonHelper.getStringOrDefaultFromFormData(entityExt.getData(), ClueEnum.COMPANY_NAME.getAttr(), "");
                errorDataList.add(name);
            }
        }
        List<Long> allowDeleteClueId = new ArrayList<>();
        UserVO loginUser = clueDeleteBatchDTO.getLoginUser();
        Boolean noPermission = !loginUser.isAdminOrBoss() && !loginUser.isMaxDataPermission();
        List<String> userIdIn = new ArrayList<>();
        if (noPermission) {
            UserEntity userEntity = new UserEntity();
            BeanUtil.copyProperties(loginUser, userEntity);
            Integer dataPermission = userModel.getDataPermission(userEntity, SaasMarkEnum.SAAS, XbbRefTypeEnum.CLUE.getCode(), null);
            if (Objects.equals(dataPermission, DataPermissionEnum.SELF.getCode())) {
                //数据权限为本人时
                userIdIn = Collections.singletonList(loginUser.getUserId());
            } else {
                //数据权限不为本人时，需要判断下属员工是否是负责人
                userIdIn = userModel.getSubIdListByDataPermission(dataPermission, loginUser.getUserId(), loginUser.getCorpid(), BasicConstant.ONE, false);
            }
        }

        Iterator<PaasFormDataEntityExt> iterator = clueList.iterator();
        while (iterator.hasNext()) {
            PaasFormDataEntityExt next = iterator.next();
            JSONObject data = next.getData();
            Integer isPublic = getIntegerOrDefaultFromFormData(data, ClueEnum.IS_PUBLIC.getAttr(), 0);
            // 除公海线索且不是最大的数据权限，自己或其下属不是负责人则不能删除该线索
            if (noPermission && !Objects.equals(isPublic, 1) && !saasDetailPermissionHelp.checkDelPermission(userIdIn, next, XbbRefTypeEnum.CLUE.getCode())) {
                String clueName = FastJsonHelper.getStringOrDefaultFromFormData(data, ClueEnum.COMPANY_NAME.getAttr(), "");
                errorTypeSet.add(I18nMessageUtil.getMessage(ErrorMessageConstant.NO_PERMISSION_CLUE_DEL));
                errorDataList.add(clueName);
                iterator.remove();
                continue;
            }
            allowDeleteClueId.add(next.getDataId());
        }


        List<String> nameList = new ArrayList<>(allowDeleteClueId.size());
        try {
            for(PaasFormDataEntityExt clue : clueList){
                String name = FastJsonHelper.getStringOrDefaultFromFormData(clue.getData(), ClueEnum.COMPANY_NAME.getAttr(), "");
                nameList.add(name);
            }
            if(!allowDeleteClueId.isEmpty()) {
                List<Long> isPublicClueIdIn = new ArrayList<>();
                List<UpdateDataEntity> updateDataList = new ArrayList<>();
                allowDeleteClueId.forEach((item)->{
                    UpdateDataEntity updateDataEntity = new UpdateDataEntity();
                    List<UpdateDataValueEntity> updateDataValueList = new ArrayList<>();
                    UpdateDataValueEntity isPublic = new UpdateDataValueEntity();
                    isPublic.setValue(1);
                    isPublic.setKey(ClueEnum.IS_PUBLIC.getAttr());
                    isPublic.setEsKey(ClueEnum.IS_PUBLIC.getAttr());
                    isPublicClueIdIn.add(item);
                    updateDataValueList.add(isPublic);
                    updateDataEntity.setId(item);
                    updateDataEntity.setCorpid(corpid);
                    long now = DateUtil.getInt();
                    updateDataEntity.setUpdateTime(now);
                    updateDataEntity.setData(updateDataValueList);
                    updateDataList.add(updateDataEntity);
                });

                if(BasicConstant.ONE.equals(clueDeleteBatchDTO.getSingleFlag())
                        && BasicConstant.ONE.equals(idIn.size())){
                    clueModel.updateBatch(updateDataList,corpid, WriteRequest.RefreshPolicy.NONE);

                    clueModel.deleteByKey(allowDeleteClueId.get(0),corpid);
                }else {
                    clueModel.updateBatch(updateDataList,corpid);
                    clueModel.deleteBatch(allowDeleteClueId, corpid);
                }
                clueDeleteBatchVO.setDeleteIds(allowDeleteClueId);
                marketActivityForStaticHelp.deleteBatchMarketActivity(allowDeleteClueId, XbbRefTypeEnum.CLUE ,corpid, BasicConstant.ONE);
                // 删除团队关系
                ClueUserDeleteBatchDTO clueUserDeleteBatchDTO = new ClueUserDeleteBatchDTO();
                BeanUtil.copyProperties(clueDeleteBatchDTO, clueUserDeleteBatchDTO);
                clueUserDeleteBatchDTO.setClueIdIn(idIn);
                clueUserService.deleteBatch(clueUserDeleteBatchDTO);
            }
            List<String> errorTypeList = new ArrayList<>(errorTypeSet);

            OperateTypeEnum operateTypeEnum = OperateTypeEnum.DELETE;
            if (Objects.equals(1,clueDeleteBatchDTO.getIsBusinessRule())) {
                operateTypeEnum = OperateTypeEnum.RULE_DELETE;
            }
            //生成删除日志(区分单个删除和批量删除)
            String userId = clueDeleteBatchDTO.getUserId();
            String userName = clueDeleteBatchDTO.getLoginUserName();

            clueDeleteBatchVO.setDeleteIds(allowDeleteClueId);
            clueDeleteBatchVO.setErrorDataList(errorDataList);
            clueDeleteBatchVO.setErrorTypeList(errorTypeList);
            clueDeleteBatchVO.setErrorDataMemo(SaasDeleteHelp.getErrorDataMemo(errorTypeList, errorDataList));


            String nameStr = StringUtils.join(nameList, "，");
            if(allowDeleteClueId.size() > 1){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_BATCH_DELETE_FORM_DETAIL), userName, XbbRefTypeEnum.CLUE.getName(), idIn.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(ClueEnum.COMPANY_NAME.getAttrName());
                infoArrPojo.setContent(nameStr);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, userName, OperateModuleTypeEnum.CLUE, operateTypeEnum,
                        "", "", memo, clueDeleteBatchDTO.getHttpHeader());
            } else if (Objects.equals(allowDeleteClueId.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_DELETE_WORK), userName, XbbRefTypeEnum.CLUE.getName(), nameStr);
                mongoLogHelp.buildLog(corpid, userId, userName, OperateModuleTypeEnum.CLUE, operateTypeEnum,
                        idIn.get(0).toString(), nameStr, memo, clueDeleteBatchDTO.getHttpHeader());
            }

        } catch (Exception e) {
            updateRollback(clueDeleteBatchDTO.getDataIdList(), corpid);
            LOG.error("clueServiceImpl.deleteBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }

        return clueDeleteBatchVO;
    }

    /**
     * 删除跟进记录
     * @param clueDeleteBatchDTO 前端传参
     * @param allowDeleteCustomerId 需要删除的客户id
     * @return void
     * @throws XbbException 业务异常
     */
    private List<Long> deleteCustomerCommunicate(ClueDeleteBatchDTO clueDeleteBatchDTO, List<Long> allowDeleteCustomerId) throws XbbException {
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        String corpid = clueDeleteBatchDTO.getCorpid();
        List<Long> customerCommunicateIdIn = new ArrayList<>();
        try {
            List<Long> deleteIdIn = new ArrayList<>();
            allowDeleteCustomerId.forEach(item->{
                if (Objects.nonNull(item)) {
                    deleteIdIn.add(item);
                }
            });
            boolQueryBuilder.filter(termsQuery(CustomerCommunicateEnum.getEsAttr4Keyword(CustomerCommunicateEnum.COMMUNICATE_BUSINESS), deleteIdIn));
            boolQueryBuilder.filter(termQuery(StringConstant.CORPID + StringConstant.POINT + StringConstant.KEY_WORD, corpid));
            boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(StringConstant.DATA_ID);
            List<PaasFormDataEntityExt> customerCommunicateList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CUSTOMER_COMMUNICATE, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
            if (Objects.isNull(customerCommunicateList)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }

            customerCommunicateList.forEach((item)->{
                customerCommunicateIdIn.add(item.getDataId());
            });
            if (!customerCommunicateIdIn.isEmpty()) {
                CustomerCommunicateDeleteBatchDTO customerCommunicateDeleteBatchDTO = new CustomerCommunicateDeleteBatchDTO();
                BeanUtil.copyProperties(clueDeleteBatchDTO, customerCommunicateDeleteBatchDTO, true);
                customerCommunicateDeleteBatchDTO.setIdIn(customerCommunicateIdIn);
                customerCommunicateService.deleteBatch(customerCommunicateDeleteBatchDTO);
            }
        } catch (Exception e) {
            LOG.error("clueServiceImpl.deleteCustomerCommunicate 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return customerCommunicateIdIn;
    }

    /**
     * 更新时回滚
     * @param idIn
     * @param corpid
     * @throws XbbException
     */
    private void updateRollback(List<Long> idIn, String corpid) throws XbbException {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("idIn", idIn);
        if (Objects.isNull(idIn) || idIn.isEmpty()) {
            return;
        }
        param.put(StringConstant.CORPID, corpid);
        List<ClueEntityExt> clueEntityExts = clueModel.findEntitys(param);
        if (CollectionUtils.isNotEmpty(clueEntityExts)) {
            for (ClueEntityExt item : clueEntityExts) {
                PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
                BeanUtil.copyProperties(item, paasFormDataEntity);
                proEsHelper.reductionEsInUpdate(paasFormDataEntity, item.getId(), corpid, IndexTypeEnum.IDX_SAAS_CLUE);
            }
        }
    }

    @Override
    public CustomerEditAttrUpdateVO batchEditAttr(CustomerEditAttrUpdateDTO customerEditAttrUpdateDTO) throws XbbException {
        CustomerEditAttrUpdateVO customerEditAttrUpdateVO = new CustomerEditAttrUpdateVO();
        try {
            Map<String, Object> param = BeanUtil.convertBean2Map(customerEditAttrUpdateDTO, true);
            param.put("idIn", customerEditAttrUpdateDTO.getDataIdList());
            List<ClueEntityExt> clueEntityExts = clueModel.findEntitys(param);
            if(Objects.isNull(clueEntityExts)) {
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001);
            }
            Integer isPublic = clueEntityExts.get(BasicConstant.ZERO).getData().getInteger(ClueEnum.IS_PUBLIC.getAttr());
            if (!Objects.equals(BasicConstant.ONE, isPublic)) {
                List<String> errorNameList = new ArrayList<>();
                //权限团队校验前置了
                List<Long> errorIdList = new ArrayList<>();
//                List<Long> errorIdList = userTeamHelp.batchTeamMembersCheckEditPermission(customerEditAttrUpdateDTO.getBusinessType(), customerEditAttrUpdateDTO.getSaasMark(),
//                        customerEditAttrUpdateDTO.getMenuId(), customerEditAttrUpdateDTO.getLoginUser(), customerEditAttrUpdateDTO.getDistributorMark(),
//                        customerEditAttrUpdateDTO.getDataIdList(), null);
                for (ClueEntityExt clueEntityExt : clueEntityExts) {
                    if (errorIdList.contains(clueEntityExt.getDataId())) {
                        errorNameList.add(clueEntityExt.getData().getString(ClueEnum.COMPANY_NAME.getAttr()));
                    }
                }
                String nameStr = org.apache.commons.lang.StringUtils.join(errorNameList, "、");
                if (CollectionUtils.isNotEmpty(errorNameList)) {
                    throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271038.getCode(), String.format(UserTeamErrorCodeEnum.API_ERROR_271038.getMsg(), nameStr));
                }
            }
            List<Long> updateIdList = new ArrayList<>();
            List<ClueUpdateDTO> clueUpdateDTOS = new ArrayList<>();
            customerEditAttrUpdateDTO.getDataIdList().forEach((item)->{
                ClueUpdateDTO customerUpdateDTO = new ClueUpdateDTO();
                customerUpdateDTO.setId(item);
                updateIdList.add(item);
                JSONObject data = ProSaveHelp.getBatchUpdateData(customerEditAttrUpdateDTO.getFieldEditedList());
                customerUpdateDTO.setData(data);
                clueUpdateDTOS.add(customerUpdateDTO);
            });
            if (!clueUpdateDTOS.isEmpty()) {
                ClueUpdateBatchDTO clueUpdateBatchDTO = new ClueUpdateBatchDTO();
                BeanUtil.copyProperties(customerEditAttrUpdateDTO, clueUpdateBatchDTO);
                clueUpdateBatchDTO.setClueUpdateDTOS(clueUpdateDTOS);
                clueUpdateBatchDTO.setFormId(customerEditAttrUpdateDTO.getFormId());
                List<String> attrList = ProSaveHelp.getAttrList(customerEditAttrUpdateDTO.getFieldEditedList());
                clueUpdateBatchDTO.setAttrList(attrList);
                clueUpdateBatch(clueUpdateBatchDTO);
                customerEditAttrUpdateVO.setUpdateIdList(updateIdList);
            }
            // 批量编辑日志
            List<String> updataItemList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            List<Long> dataIdList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            for (ClueEntityExt item : clueEntityExts) {
                dataIdList.add(item.getId());
                JSONObject data = item.getData();
                String serialNo = item.getSerialNo();
                String opObjectName = data.getString(ClueEnum.COMPANY_NAME.getAttr());
                StringBuilder sb = new StringBuilder();
                opObjectName = opObjectName == null ? serialNo : sb.append(serialNo).append("（").append(opObjectName).append("）").toString();
                updataItemList.add(opObjectName);
            }
            String updataItem = StringUtils.join(updataItemList, "，");
            String userId = customerEditAttrUpdateDTO.getUserId();
            String corpid = customerEditAttrUpdateDTO.getCorpid();
            String loginUserName = customerEditAttrUpdateDTO.getLoginUserName();
            // 标签特殊处理
            Integer fieldType = customerEditAttrUpdateDTO.getFieldType();
            Boolean isFieldDependence = customerEditAttrUpdateDTO.getIsFieldDependence();
            logHelp.analysisLabel(corpid, fieldType, isFieldDependence,customerEditAttrUpdateDTO.getLogFieldEditedList());

            String changedLogItemsStr = logHandleHelp.getChangedLogItemsStr(customerEditAttrUpdateDTO.getLogFieldEditedList());
            if(dataIdList.size() > 1 ){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_BATCH_ATTR), loginUserName, XbbRefTypeEnum.CLUE.getName(),
                        changedLogItemsStr, dataIdList.size());
                List<InfoArrPojo> infoArrPojoList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                InfoArrPojo infoArrPojo = new InfoArrPojo();
                infoArrPojo.setTitle(XbbRefTypeEnum.CLUE.getName());
                infoArrPojo.setContent(updataItem);
                infoArrPojoList.add(infoArrPojo);
                mongoLogHelp.buildLog4InfoArr(infoArrPojoList, corpid, userId, loginUserName, OperateModuleTypeEnum.CLUE, OperateTypeEnum.EDIT,
                        "", "", memo, customerEditAttrUpdateDTO.getHttpHeader());
            } else if (Objects.equals(dataIdList.size(), 1)){
                String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_USER_UPDATE_FORM_DATA_ATTR), loginUserName, XbbRefTypeEnum.CLUE.getName(), updataItem,
                        changedLogItemsStr);
                mongoLogHelp.buildLog(corpid, userId, loginUserName, OperateModuleTypeEnum.CLUE, OperateTypeEnum.EDIT,
                        dataIdList.get(0).toString(), updataItem, memo, customerEditAttrUpdateDTO.getHttpHeader());
            }
        } catch (XbbException e){
            throw e;
        } catch (Exception e) {
            LOG.error("clueServiceImpl.batchEditAttr 执行出错", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return customerEditAttrUpdateVO;
    }

    @Override
    public ClueUpdateBatchVO clueUpdateBatch(ClueUpdateBatchDTO clueUpdateBatchDTO) throws XbbException {
        ClueUpdateBatchVO customerUpdateBatchVO = new ClueUpdateBatchVO();
        try {
            String corpid = clueUpdateBatchDTO.getCorpid();
            List<UpdateDataEntity> updateList = new ArrayList<>();
            List<ClueUpdateDTO> clueUpdateDTOS = clueUpdateBatchDTO.getClueUpdateDTOS();
            if (Objects.nonNull(clueUpdateDTOS) && !clueUpdateDTOS.isEmpty()) {
                clueUpdateDTOS.forEach((item)->{
                    updateList.add(ExplainUtil.getUpdateData(item.getId(), item.getData(), corpid));
                });
            }
            if (!updateList.isEmpty()) {
                clueModel.updateBatch(updateList, corpid);
                //快速编辑, 触发评分
                updateScore4BatchUpdate(corpid,updateList,clueUpdateBatchDTO);
            }
            dealStaticMarket(corpid, clueUpdateDTOS);
        } catch (Exception e) {
            LOG.error("clueServiceImpl.clueUpdateBatch 执行出错：", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return customerUpdateBatchVO;
    }

    @Override
    public void dataConsistencyUpdateMarketActivity(String corpid, Long dataId, String name) throws XbbException{
        try {
            BoolQueryBuilder filter = boolQuery()
                    .filter(termQuery("corpid.keyword", corpid))
                    .filter(termQuery("del", 0))
                    .filter(termQuery(ClueEnum.getEsAttr4Keyword(ClueEnum.MARKET_ACTIVITY_ID), dataId));
            List<String> fieldList = new ArrayList<>();
            fieldList.add(FieldTypeEnum.DATAID.getAlias());
            List<PaasFormDataEntityExt> esEntities = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_CLUE, filter, PaasFormDataEntityExt.class, fieldList);
            if (CollectionsUtil.isEmpty(esEntities)) {
                return;
            }
            List<Long> ids = new ArrayList<>();
            for (PaasFormDataEntityExt esEntity : esEntities) {
                ids.add(esEntity.getDataId());
            }

            proUpdateHelp.updateByIds(XbbRefTypeEnum.CLUE.getCode(), corpid, ids, ClueEnum.MARKET_ACTIVITY_NAME.getAttr(), name);
        } catch (Exception e) {
            LOG.error("ClueServiceImpl.dataConsistencyUpdateMarketActivity fail， corpid=" + corpid + " clueId=" + dataId + "  name=" + name, e);
        }
    }

    @Override
    public void afterSaveForWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long dataId = newPaasFormDataEntity.getId();
        if (Objects.isNull(saasFormSaveDTO.getOwnerId()) || (Objects.nonNull(saasFormSaveDTO.getOwnerId()) && saasFormSaveDTO.getOwnerId().isEmpty())) {
            saasFormSaveDTO.setSubBusinessType(XbbRefTypeEnum.CLUE_PUBLIC.getCode());
        }

        SaasNeedRedundantAttrPojo saasNeedRedundantAttrPoJo = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo();
        if (Objects.nonNull(saasNeedRedundantAttrPoJo)) {
            // 团队保存
            teamDataHelp.saveUserTeam(saasNeedRedundantAttrPoJo, dataId, saasFormSaveDTO.getNewPaasFormDataEntity(), saasFormSaveDTO.getIsImport(),true);
        }
    }

    @Override
    public void afterSaveForUpdateWorkflow(SaasFormSaveDTO saasFormSaveDTO) throws XbbException {
        PaasFormDataEntity newPaasFormDataEntity = saasFormSaveDTO.getNewPaasFormDataEntity();
        Long dataId = newPaasFormDataEntity.getId();
        JSONObject oldData = saasFormSaveDTO.getOldData();

        SaasNeedRedundantAttrPojo saasNeedRedundantAttrPoJo = saasFormSaveDTO.getSaasNeedRedundantAttrPoJo();
        if (Objects.nonNull(saasNeedRedundantAttrPoJo)) {
            // 团队保存
            teamDataHelp.saveUserTeam(saasFormSaveDTO.getSaasNeedRedundantAttrPoJo(), dataId, saasFormSaveDTO.getNewPaasFormDataEntity(), saasFormSaveDTO.getIsImport(),true);
        }


    }

    @Override
    public ChangeClueStatusVO invalidClue(ChangeClueStatusDTO changeClueStatusDTO) throws XbbException {
        UserVO loginUser = changeClueStatusDTO.getLoginUser();
        Long dataId = changeClueStatusDTO.getDataId();
        String corpid = changeClueStatusDTO.getCorpid();
        Integer businessType = XbbRefTypeEnum.CLUE.getCode();
        //获取数据
        PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormDataWithTeam(corpid, SaasMarkEnum.SAAS.getCode(), businessType, dataId);
        if (paasFormDataEntityExt == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        //校验表单编辑权限
        if (!loginUser.getPermSet().contains(ProPermissionAliasEnum.CLUE_UPDATE.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CLUE_UPDATE.getMemo()));
        }
        //校验数据权限(团队权限&共享权限)
        VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
        boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
        if (!hasDataPermission){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CLUE_UPDATE.getMemo()));
        }

        ChangeClueStatusVO changeClueStatusVO = new ChangeClueStatusVO();
        changeClueStatusVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
        changeClueStatusVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
        changeClueStatusVO.setFormDataId(changeClueStatusDTO.getDataId());

        JSONObject data = paasFormDataEntityExt.getData();
        String oldStatus = FastJsonHelper.getStringOrDefaultFromFormData(data, ClueEnum.CLUE_STATUS.getAttr(), "");

        if (Objects.equals(oldStatus, ClueStatusEnum.TRANSFORMED.getCode())) {
            BoolQueryBuilder boolQueryBuilder = boolQuery();
            boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
            boolQueryBuilder.filter(termsQuery(StringConstant.DEL, Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.DELETE.getDel())));
            boolQueryBuilder.filter(termQuery(CustomerManagementEnum.getEsAttr4Keyword(CustomerManagementEnum.CLUE_ID), dataId));
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(boolQueryBuilder);
            IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

            SearchRequest searchRequest = new SearchRequest(customerIndex.getIndex());
            searchRequest.source(sourceBuilder);
            CountRequest countRequest = new CountRequest(searchRequest.indices()[0]);
            countRequest.query(searchRequest.source().query());
            Long count = xbbElasticsearchRestTemplate.count(countRequest);
            if (Objects.nonNull(count) && count > 0) {
                throw new XbbException(ClueErrorCodeEnum.API_ERROR_1110024);
            }
        }
        String newStatus = ClueStatusEnum.INVALID.getCode();
        String invalidReason = changeClueStatusDTO.getInvalidReason();
        if (Objects.equals(oldStatus, newStatus)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, ErrorMessageConstant.STATUS_NOT_MODIFIED);
        } else {

            Integer noApprovalRequired = 1;
            if (commonHelp.isOpenWorkFlow(corpid)) {
                // 工作流
                noApprovalRequired = startWorkflow(paasFormDataEntityExt, corpid, newStatus, loginUser);
            } else {
                // 老审批
                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                params.put("del", 0);
                params.put("corpid", corpid);
                params.put("formId", paasFormDataEntityExt.getFormId());
                params.put("businessType", businessType);
                params.put("enable", 1);
                List<PaasProcessTemplateEntityExt> paasProcessTemplateEntityExtList = paasProcessTemplateModel.list(params);
                List<String> attrs = Arrays.asList(ClueEnum.CLUE_STATUS.getAttr(), ClueEnum.INVALID_REASON.getAttr(), ClueEnum.INVALID_MEMO.getAttr());
                List<String> needAttrs = new ArrayList<>();
                if (CollectionUtils.isNotEmpty(paasProcessTemplateEntityExtList)) {
                    needAttrs = paasProcessTemplateEntityExtList.get(0).getNeedApproveFieldList();
                    needAttrs.retainAll(attrs);
                }
                if (CollectionUtils.isNotEmpty(needAttrs)) {
                    JSONObject newData = (JSONObject) CloneUtil.deepClone(paasFormDataEntityExt.getData());
                    newData.put(ClueEnum.CLUE_STATUS.getAttr(), newStatus);
                    Map<Integer, List<UserTeamEntity>> userMap = userTeamService.getUserTeam(paasFormDataEntityExt.getId(), corpid, businessType);
                    // 负责人
                    if (userMap.containsKey(1)) {
                        List<UserTeamEntity> mainUserList = userMap.get(1);
                        List<String> mainIdList = new ArrayList<>();
                        for (UserTeamEntity userTeamEntity : mainUserList) {
                            mainIdList.add(userTeamEntity.getUserId());
                        }
                        newData.put(ClueEnum.OWNER_ID.getAttr(), mainIdList);
                    }
                    if (userMap.containsKey(0)) {
                        List<UserTeamEntity> coUserList = userMap.get(0);
                        List<String> coIdList = new ArrayList<>();
                        for (UserTeamEntity userTeamEntity : coUserList) {
                            coIdList.add(userTeamEntity.getUserId());
                        }
                        newData.put(ClueEnum.COUSERID.getAttr(), coIdList);
                    }
                    newData.put(ClueEnum.INVALID_REASON.getAttr(), invalidReason);
                    newData.put(ClueEnum.INVALID_MEMO.getAttr(), changeClueStatusDTO.getMemo());

                    StartProcessDTO startProcessDTO = new StartProcessDTO();
                    BeanUtil.copyProperties(changeClueStatusDTO, startProcessDTO);
                    BeanUtil.copyProperties(paasFormDataEntityExt, startProcessDTO);
                    startProcessDTO.setData(newData);
                    startProcessDTO.setFormDataId(paasFormDataEntityExt.getId());
                    startProcessDTO.setCreatorId(changeClueStatusDTO.getUserId());
                    startProcessDTO.setSaasMark(1);
                    startProcessDTO.setBusinessType(businessType);
                    StartProcessVO startProcessVO = processStartHelp.startProcess(startProcessDTO, paasFormDataEntityExt);
                    noApprovalRequired = startProcessVO.getNoApprovalRequired();
                }
            }



            if (Objects.equals(noApprovalRequired, 1)) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(ClueEnum.CLUE_STATUS.getAttr(), newStatus);
                param.put(ClueEnum.INVALID_REASON.getAttr(), invalidReason);
                param.put(ClueEnum.INVALID_MEMO.getAttr(), changeClueStatusDTO.getMemo());
                clueModel.jsonsetNoSubById(corpid, dataId, param);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(ClueEnum.CLUE_STATUS.getAttr(), newStatus);
                List<ClueUpdateDTO> list = new ArrayList<>();
                list.add(new ClueUpdateDTO(dataId, jsonObject));
                dealStaticMarket(corpid, list);
                Runnable runnable = () -> {
                    try {
                        // 线索状态变更消息推送
                        String clueName = data.getString(ClueEnum.COMPANY_NAME.getAttr());
                        List<String> clueUserIdList = clueUserModel.getClueUserIdList(corpid, dataId, null);
                        List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.CLUE_CHANGE_PUSH.getCode(),
                                PushTypeEnum.CLUE_CHANGE_PUSH.getSubCode(), loginUser, paasFormDataEntityExt);
                        pushUserList.addAll(clueUserIdList);
                        //去除当前操作人，可能在上一行中加回来。。。
                        pushUserList.remove(changeClueStatusDTO.getUserId());
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(paasFormDataEntityExt.getAppId(), paasFormDataEntityExt.getMenuId(), paasFormDataEntityExt.getFormId(), dataId, Collections.singletonList(dataId), SaasMarkEnum.SAAS.getCode(), businessType, XbbRefTypeEnum.ALL_CLUE.getCode());
                        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(dataId), 0, null, I18nMessageUtil.getMessage(CluePushConstant.CLUE_STATUS_CHANGE_TITLE), String.format(I18nMessageUtil.getMessage(CluePushConstant.CLUE_STATUS_CHANGE_CONTENT), changeClueStatusDTO.getLoginUserName(), clueName, ClueStatusEnum.INVALID.getName()), null, options);
                        baseProducer.sendMessage(PushTypeEnum.CLUE_CHANGE_PUSH, messageRabbitMqDTO);
                        //评分更新(线索详情页，右上角点击无效，修改线索状态) clueModel.jsonsetNoSubById(corpid, dataId, param)更新了一次，所以不能取paasFormDataEntityExt的数据
                        scoreCalculateService.asyncUpdateSingleDataScore(XbbRefTypeEnum.CLUE,corpid,dataId,null);
                    } catch (Exception e) {
                        LOG.error("线索状态变更无效消息推送", e);
                    }
                };
                threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
            } else {
                changeClueStatusVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                changeClueStatusVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
                PaasProcessDataEntity paasProcessDataEntity = new PaasProcessDataEntity();
                paasProcessDataEntity.setCorpid(changeClueStatusDTO.getCorpid());
                paasProcessDataEntity.setFormDataId(changeClueStatusDTO.getDataId());
                paasProcessDataEntity.setBusinessType(businessType);
                paasProcessDataEntity.setSaasMark(1);
                proModelService.updateFormDataStatus(paasProcessDataEntity, FlowStatusEnum.IN_APPROVAL.getType());
            }
        }
        return changeClueStatusVO;
    }

    @Override
    public ChangeClueStatusVO followClue(ChangeClueStatusDTO changeClueStatusDTO) throws XbbException {
        UserVO loginUser = changeClueStatusDTO.getLoginUser();
        Long dataId = changeClueStatusDTO.getDataId();
        String corpid = changeClueStatusDTO.getCorpid();
        Integer businessType = XbbRefTypeEnum.CLUE.getCode();
        //获取数据
        PaasFormDataEntityExt paasFormDataEntityExt = formDataHelp.getFormDataWithTeam(corpid, SaasMarkEnum.SAAS.getCode(), businessType, dataId);
        if (paasFormDataEntityExt == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_DATA_NOT_EXIST);
        }
        //校验表单编辑权限
        if (!loginUser.getPermSet().contains(ProPermissionAliasEnum.CLUE_UPDATE.getAlias())) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CLUE_UPDATE.getMemo()));
        }
        //校验数据权限(团队权限&共享权限)
        VerifyUpdatePermissionDTO verifyUpdatePermissionDTO = new VerifyUpdatePermissionDTO(loginUser, paasFormDataEntityExt);
        boolean hasDataPermission = commonPermissionHelp.checkEditPermissionWithoutTeamEdit(verifyUpdatePermissionDTO);
        if (!hasDataPermission){
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100050, String.format(SystemErrorCodeEnum.API_ERROR_100050.getMsg(), ProPermissionAliasEnum.CLUE_UPDATE.getMemo()));
        }

        ChangeClueStatusVO changeClueStatusVO = new ChangeClueStatusVO();
        changeClueStatusVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_RETURN_MSG));
        changeClueStatusVO.setCode(PaasConstant.FORM_ADD_RETURN_CODE);
        changeClueStatusVO.setFormDataId(changeClueStatusDTO.getDataId());
        JSONObject data = paasFormDataEntityExt.getData();
        String oldStatus = FastJsonHelper.getStringOrDefaultFromFormData(data, ClueEnum.CLUE_STATUS.getAttr(), "");
        String newStatus = ClueStatusEnum.FOLLOWING_UP.getCode();
        if (Objects.equals(oldStatus, newStatus)) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, ErrorMessageConstant.STATUS_NOT_MODIFIED);
        } else {
            if (Objects.equals(oldStatus, ClueStatusEnum.INVALID.getCode())) {
                BoolQueryBuilder boolQueryBuilder = boolQuery();
                boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                boolQueryBuilder.filter(termsQuery(StringConstant.DEL, Arrays.asList(DelEnum.NORMAL.getDel(), DelEnum.DELETE.getDel())));
                boolQueryBuilder.filter(termQuery(CustomerManagementEnum.getEsAttr4Keyword(CustomerManagementEnum.CLUE_ID), dataId));
                SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
                sourceBuilder.query(boolQueryBuilder);
                IndexTypeEnum customerIndex = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());

                SearchRequest searchRequest = new SearchRequest(customerIndex.getIndex());
                searchRequest.source(sourceBuilder);
                CountRequest countRequest = new CountRequest(searchRequest.indices()[0]);
                countRequest.query(searchRequest.source().query());
                Long count = xbbElasticsearchRestTemplate.count(countRequest);
                if (Objects.nonNull(count) && count > 0) {
                    throw new XbbException(ClueErrorCodeEnum.API_ERROR_1110018);
                }
            }
            Integer noApprovalRequired = 1;
            if (commonHelp.isOpenWorkFlow(corpid)) {
                noApprovalRequired = startWorkflow(paasFormDataEntityExt, corpid, newStatus, loginUser);
            } else {
                Map<String, Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                params.put("del", 0);
                params.put("corpid", corpid);
                params.put("formId", paasFormDataEntityExt.getFormId());
                params.put("businessType", businessType);
                params.put("enable", 1);
                List<PaasProcessTemplateEntityExt> paasProcessTemplateEntityExtList = paasProcessTemplateModel.list(params);

                if (paasProcessTemplateEntityExtList.size() > 0 && paasProcessTemplateEntityExtList.get(0).getNeedApproveFieldList().contains(ClueEnum.CLUE_STATUS.getAttr())) {
                    JSONObject newData = (JSONObject) CloneUtil.deepClone(paasFormDataEntityExt.getData());
                    newData.put(ClueEnum.CLUE_STATUS.getAttr(), newStatus);
                    Map<Integer, List<UserTeamEntity>> userMap = userTeamService.getUserTeam(paasFormDataEntityExt.getId(), corpid, businessType);
                    // 负责人
                    if (userMap.containsKey(1)) {
                        List<UserTeamEntity> mainUserList = userMap.get(1);
                        List<String> mainIdList = new ArrayList<>();
                        for (UserTeamEntity userTeamEntity : mainUserList) {
                            mainIdList.add(userTeamEntity.getUserId());
                        }
                        newData.put(ClueEnum.OWNER_ID.getAttr(), mainIdList);
                    }
                    if (userMap.containsKey(0)) {
                        List<UserTeamEntity> coUserList = userMap.get(0);
                        List<String> coIdList = new ArrayList<>();
                        for (UserTeamEntity userTeamEntity : coUserList) {
                            coIdList.add(userTeamEntity.getUserId());
                        }
                        newData.put(ClueEnum.COUSERID.getAttr(), coIdList);
                    }
                    StartProcessDTO startProcessDTO = new StartProcessDTO();
                    BeanUtil.copyProperties(changeClueStatusDTO, startProcessDTO);
                    BeanUtil.copyProperties(paasFormDataEntityExt, startProcessDTO);
                    startProcessDTO.setData(newData);
                    startProcessDTO.setFormDataId(paasFormDataEntityExt.getId());
                    startProcessDTO.setCreatorId(changeClueStatusDTO.getUserId());
                    startProcessDTO.setSaasMark(1);
                    startProcessDTO.setBusinessType(businessType);
                    StartProcessVO startProcessVO = processStartHelp.startProcess(startProcessDTO, paasFormDataEntityExt);
                    noApprovalRequired = startProcessVO.getNoApprovalRequired();
                }
            }


            if (Objects.equals(noApprovalRequired, 1)) {
                Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                param.put(ClueEnum.CLUE_STATUS.getAttr(), newStatus);
                clueModel.jsonsetNoSubById(corpid, dataId, param);
                JSONObject jsonObject = new JSONObject();
                jsonObject.put(ClueEnum.CLUE_STATUS.getAttr(), newStatus);
                List<ClueUpdateDTO> list = new ArrayList<>();
                list.add(new ClueUpdateDTO(dataId, jsonObject));
                dealStaticMarket(corpid, list);
                Runnable runnable = () -> {
                    try {
                        // 线索状态变更消息推送
                        String clueName = data.getString(ClueEnum.COMPANY_NAME.getAttr());
                        List<String> clueUserIdList = clueUserModel.getClueUserIdList(corpid, dataId, null);
                        List<String> pushUserList = pushHelper.getUserIdListByPushSetRule(corpid, PushTypeEnum.CLUE_CHANGE_PUSH.getCode(),
                                PushTypeEnum.CLUE_CHANGE_PUSH.getSubCode(), loginUser, paasFormDataEntityExt);
                        pushUserList.addAll(clueUserIdList);
                        //去除当前操作人，可能在上一行中加回来。。。
                        pushUserList.remove(changeClueStatusDTO.getUserId());
                        PushRefTypePojo.Options options = new PushRefTypePojo.Options(paasFormDataEntityExt.getAppId(), paasFormDataEntityExt.getMenuId(), paasFormDataEntityExt.getFormId(), dataId, Collections.singletonList(dataId), SaasMarkEnum.SAAS.getCode(), businessType, XbbRefTypeEnum.ALL_CLUE.getCode());
                        MessageRabbitMqDTO messageRabbitMqDTO = new MessageRabbitMqDTO(corpid, pushUserList, Collections.singletonList(dataId), 0, null, I18nMessageUtil.getMessage(CluePushConstant.CLUE_STATUS_CHANGE_TITLE), String.format(I18nMessageUtil.getMessage(CluePushConstant.CLUE_STATUS_CHANGE_CONTENT), changeClueStatusDTO.getLoginUserName(), clueName, ClueStatusEnum.FOLLOWING_UP.getName()), null, options);
                        baseProducer.sendMessage(PushTypeEnum.CLUE_CHANGE_PUSH, messageRabbitMqDTO);
                        //评分更新（线索状态修改为 跟进中）
                        scoreCalculateService.asyncUpdateSingleDataScore(XbbRefTypeEnum.CLUE,corpid,dataId,paasFormDataEntityExt);
                    } catch (Exception e) {
                        LOG.error("线索状态变更跟进中消息推送", e);
                    }
                };
                threadPoolBeanConfig.addUpdateDelThreadPool().execute(runnable);
            } else {
                changeClueStatusVO.setMsg(I18nMessageUtil.getMessage(MessageConstant.FORM_ADD_PROCESS_RETURN_MSG));
                changeClueStatusVO.setCode(PaasConstant.FORM_ADD_PROCESS_RETURN_CODE);
                PaasProcessDataEntity paasProcessDataEntity = new PaasProcessDataEntity();
                paasProcessDataEntity.setCorpid(changeClueStatusDTO.getCorpid());
                paasProcessDataEntity.setFormDataId(changeClueStatusDTO.getDataId());
                paasProcessDataEntity.setBusinessType(businessType);
                paasProcessDataEntity.setSaasMark(1);
                proModelService.updateFormDataStatus(paasProcessDataEntity, FlowStatusEnum.IN_APPROVAL.getType());
            }
        }
        return changeClueStatusVO;
    }



    @Override
    public void updateBatchLabelAttr(AddLabelDTO addLabelDTO, List<PaasFormDataEntityExt> addBatchList, Boolean addOrDelete) throws XbbException {
        ClueUpdateBatchDTO paySheetUpdateBatchDTO = new ClueUpdateBatchDTO();
        BeanUtil.copyProperties(addLabelDTO, paySheetUpdateBatchDTO);
        List<ClueUpdateDTO> paySheetList = new ArrayList<>();
        addBatchList.forEach(item->{
            ClueUpdateDTO paySheetUpdateDTO= new ClueUpdateDTO();
            paySheetUpdateDTO.setData(item.getData());
            paySheetUpdateDTO.setId(item.getId());
            paySheetList.add(paySheetUpdateDTO);
        });
        paySheetUpdateBatchDTO.setClueUpdateDTOS(paySheetList);
        clueUpdateBatch(paySheetUpdateBatchDTO);

    }

    /**
     * 开始工作流
     * @param paasFormDataEntityExt
     * @param corpid
     * @param newStatus
     * @param loginUser
     * @return
     * @throws XbbException
     */
    private Integer  startWorkflow(PaasFormDataEntityExt paasFormDataEntityExt, String corpid, String newStatus, UserVO loginUser) throws XbbException{
        Integer noApprovalRequired = 1;
        Long formId = paasFormDataEntityExt.getFormId();
        Long dataId = paasFormDataEntityExt.getId();
        PaasFormExplainEntity paasFormExplainEntity = paasFormExplainModel.getByFormId(formId, corpid);
        Map<String, FieldAttrEntity> explainMap = ExplainUtil.getExplainMap(paasFormExplainEntity.getExplains(), null);
        // 新工作流
        List<WorkflowEntity> workflowEntities = workflowFormDataOperationService.getSatisfyTriggerEntitys(corpid, formId, XbbRefTypeEnum.CLUE.getCode(), Arrays.asList(TriggerEventTypeEnum.ONLY_UPDATE.getType(), TriggerEventTypeEnum.ADD_OR_UPDATE.getType()));
        for (WorkflowEntity workflowEntity : workflowEntities) {
            WorkflowNodeEntity startNode = workflowNodeModel.getByUId(workflowEntity.getId(), corpid, "startNode");
            FormTriggerNode formTriggerNode = JSON.parseObject(startNode.getConfigData(), FormTriggerNode.class);
            if (formTriggerNode.getNeedApproveFields().contains(ClueEnum.CLUE_STATUS.getAttr())) {
                BusinessRuleInfoPojo businessRuleInfoPojo = new BusinessRuleInfoPojo(startNode.getCorpid(), startNode.getFormId(), startNode.getBusinessType(), startNode.getSaasMark(), explainMap);
                // 判断
                boolean flag = workflowFormDataOperationService.validatePreCondition(formTriggerNode.getTriggerConditions(), paasFormDataEntityExt, businessRuleInfoPojo);
                if (flag) {
                    // backup
                    JSONObject oldDataObj = (JSONObject) CloneUtil.deepClone(paasFormDataEntityExt.getData());
                    FormDataUtil.setSystemData(oldDataObj, paasFormDataEntityExt);
                    long now = DateTimeUtil.getInt();
                    List<ClueUserEntity> contactList = clueUserModel.getClueUserList(corpid, paasFormDataEntityExt.getId(), null);
                    oldDataObj.put(StringConstant.USER_TEAM, contactList);
                    WorkflowBackupDataEntity workflowBackupDataEntity = new WorkflowBackupDataEntity(corpid, paasFormDataEntityExt.getAppId(), formId, paasFormDataEntityExt.getMenuId(), 0L, 0L, paasFormDataEntityExt.getId(), oldDataObj, now, now, DelEnum.NORMAL.getDel());
                    workflowBackupDataModel.insert(workflowBackupDataEntity);

                    //构建mq消息
                    FormDataUtil.setSystemData(paasFormDataEntityExt.getData(), paasFormDataEntityExt);
                    Data oldData = new Data(startNode.getAppId(), startNode.getMenuId(), startNode.getFormId(), paasFormDataEntityExt.getId(), paasFormDataEntityExt.getData(), startNode.getBusinessType(), startNode.getSaasMark(), startNode.getId(), XbbRefTypeEnum.CLUE.getCode());
                    // 更新数据
                    Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                    param.put(ClueEnum.CLUE_STATUS.getAttr(), newStatus);
                    clueModel.jsonsetNoSubById(corpid, dataId, param);
                    paasFormDataEntityExt.getData().put(ClueEnum.CLUE_STATUS.getAttr(), newStatus);

                    WorkflowTransferPOJO workflowTransferPOJO = WorkflowTransferHelp.createTransferData(paasFormDataEntityExt, explainMap, null, null, corpid, loginUser, startNode, WorkflowOperateEnum.UPDATE.getType(), 0, XbbRefTypeEnum.CLUE.getCode());
                    workflowTransferPOJO.setBackupDataId(workflowBackupDataEntity.getId());

                    workflowTransferPOJO.setOldData(oldData);

                    WorkflowRabbitmqDTO workflowRabbitmqDTO = new WorkflowRabbitmqDTO(workflowTransferPOJO, startNode, null);
                    workflowProducer.startWorkflow(workflowRabbitmqDTO);

                    noApprovalRequired = 3;
                }
                break;
            }
        }
        return noApprovalRequired;
    }

    /**
     * 处理编辑接口(市场活动统计中间表)
     * @param corpid
     * @param clueUpdateList
     */
    public void dealStaticMarket(String corpid, List<ClueUpdateDTO> clueUpdateList) throws XbbException {
        List<StaticForUpdateDTO> list = new ArrayList<>();
        for (ClueUpdateDTO clueUpdateDTO : clueUpdateList) {
            StaticForUpdateDTO staticForUpdateDTO = new StaticForUpdateDTO();
            BeanUtil.copyProperties(clueUpdateDTO, staticForUpdateDTO);
            list.add(staticForUpdateDTO);
        }
        marketActivityForStaticHelp.updateBatchMarketActivity(list, XbbRefTypeEnum.CLUE ,corpid);
    }

    /**
     * 快速编辑之后，触发评分的更新
     * @param corpid
     * @param updateList
     */
    private void updateScore4BatchUpdate(String corpid , List<UpdateDataEntity> updateList, ClueUpdateBatchDTO clueUpdateBatchDTO){
        try{
            if(StringUtil.isNotEmpty(corpid) && CollectionsUtil.isNotEmpty(updateList) && Objects.nonNull(clueUpdateBatchDTO)){
                //列表快速编辑时的formId，attr是编辑的字段。这两个值是在列表快速编辑或者批量编辑单个字段时塞进去的，其他场景可能是空的
                Long formId = clueUpdateBatchDTO.getFormId();
                List<String> attrList = clueUpdateBatchDTO.getAttrList();
                List<Long> updateIdList = updateList.stream().map(item -> item.getId()).collect(Collectors.toList());
                if(Objects.nonNull(formId) && !attrList.isEmpty()){
                    //formId不为空，表示列表页快速编辑过来的。需要判断一下编辑的字段是否命中评分规则，再去看是否需要触发评分
                    if (scoreCalculateHelp.isTriggerScoreForQuickEdit(attrList, corpid, formId)) {
                        //评分更新（线索列表页快速编辑）
                        scoreCalculateService.asyncUpdateBatchDataScore(XbbRefTypeEnum.CLUE,corpid,updateIdList);
                    }
                }else {
                    //评分更新（其他场景的批量编辑）
                    scoreCalculateService.asyncUpdateBatchDataScore(XbbRefTypeEnum.CLUE,corpid,updateIdList);
                }
            }
        }catch (Exception e){
            LOG.error("updateScore4BatchUpdate 评分触发更新失败,e-{}-,参数 updateList-{}-",e.getMessage(), JSON.toJSONString(updateList));
        }
    }

    /**
     * 线索数据加锁
     * @param clueIdList
     * @param corpid
     */
    private Set<Long> clueAutoAssignmentLocking(List<Long> clueIdList, String corpid) {
        Set<Long> value4Set = paasRedisHelper.getValue4Set(RedisPrefixConstant.CLUE_AUTO_ALLOT, corpid);
        if (CollectionsUtil.isEmpty(value4Set)) {
            value4Set = new HashSet<>();
        }
        clueIdList.removeAll(value4Set);

        return value4Set;
    }
}
